<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Resource Finder</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Resource Finder' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">multimedia</a></li><li><a href="index.html#2">Chapter 2: Multimedia Features</a></li><li><b>Resource Finder</b></li></ul></div>
<p class="purpose">To find resources such as sound and image files.</p>

<ul class="toc"><li><a href="2-rf.html#SP1">&#167;1. Resource finder</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Resource finder.</b>This simple function is shared by the code for figures, sound effects and
internal data files. When Inform reads a sentence such as:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Sound</span><span class="plain-syntax"> </span><span class="identifier-syntax">of</span><span class="plain-syntax"> </span><span class="identifier-syntax">Organ</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">the</span><span class="plain-syntax"> </span><span class="identifier-syntax">file</span><span class="plain-syntax"> </span><span class="string-syntax">"Passacaglia.aiff"</span><span class="plain-syntax">.</span>
</pre>
<p class="commentary">it needs to find this file, which will either be in the materials for the
project, or in materials for the extension in which this sentence occurs
(if it occurs in an extension). In either case, it'll be in the <span class="extract"><span class="extract-syntax">Sounds</span></span>
subdirectory. Here <span class="extract"><span class="extract-syntax">"Sounds"</span></span> is what we will call the department name for
sound effects.
</p>

<p class="commentary">This code was introduced as part of the implementation of IE-0001, and for
the first time throws problem messages if named resources do not exist.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">check_resources_are_present</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">ResourceFinder::set_mode</span><span class="plain-syntax">(</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">val</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">check_resources_are_present</span><span class="plain-syntax"> = </span><span class="identifier-syntax">val</span><span class="plain-syntax">; </span><span class="comment-syntax"> set by </span><span class="extract"><span class="extract-syntax">-resource-checking</span></span><span class="comment-syntax"> at command line</span>
<span class="plain-syntax">}</span>

<span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="function-syntax">ResourceFinder::find_resource</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">ResourceFinder::find_resource</span></span>:<br/>Figures - <a href="2-fgr.html#SP5">&#167;5</a><br/>Sound Effects - <a href="2-se.html#SP5">&#167;5</a><br/>Internal Files - <a href="2-if.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">department</span><span class="plain-syntax">, </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">leaf</span><span class="plain-syntax">, </span><span class="identifier-syntax">wording</span><span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">inform_extension</span><span class="plain-syntax"> *</span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">Wordings::nonempty</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">E</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Extensions::corresponding_to</span><span class="plain-syntax">(</span><span class="identifier-syntax">Lexer::file_of_origin</span><span class="plain-syntax">(</span><span class="identifier-syntax">Wordings::first_wn</span><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">)));</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">materials_dept</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::resources_path</span><span class="plain-syntax">(), </span><span class="identifier-syntax">department</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">extension_dept</span><span class="plain-syntax"> = </span><span class="identifier-syntax">E</span><span class="plain-syntax">?(</span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">Extensions::materials_path</span><span class="plain-syntax">(</span><span class="identifier-syntax">E</span><span class="plain-syntax">), </span><span class="identifier-syntax">department</span><span class="plain-syntax">)):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">extension_dept</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-rf.html#SP1_1" class="named-paragraph-link"><span class="named-paragraph">Look for an extension resource</span><span class="named-paragraph-number">1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">materials_dept</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="2-rf.html#SP1_2" class="named-paragraph-link"><span class="named-paragraph">Look for a regular materials resource</span><span class="named-paragraph-number">1.2</span></a></span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">Problems::quote_source</span><span class="plain-syntax">(1, </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Problems::quote_wording</span><span class="plain-syntax">(2, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Problems::quote_stream</span><span class="plain-syntax">(3, </span><span class="identifier-syntax">department</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::handmade_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">Task::syntax_tree</span><span class="plain-syntax">(), </span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">Untestable</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax">        </span><span class="string-syntax">"You wrote %1, which means I am looking for a file called %2, but I'm "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"unable to find it. "</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">extension_dept</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax">            </span><span class="string-syntax">"The file should either be in the '%3' subfolder of the materials folder, "</span>
<span class="plain-syntax">            </span><span class="string-syntax">"or in the 'Materials/%3' subfolder of this extension."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">Problems::issue_problem_segment</span><span class="plain-syntax">(</span>
<span class="plain-syntax">            </span><span class="string-syntax">"The file should be in the '%3' subfolder of the materials folder."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Problems::issue_problem_end</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1" class="paragraph-anchor"></a><b>&#167;1.1. </b>So here we're reading the line from an extension, say <span class="extract"><span class="extract-syntax">Leipzig Organ Recitals</span></span>.
We first look for an audio file called something like
<span class="extract"><span class="extract-syntax">Leipzig Organ Recitals-v1/Materials/Sounds/Passacaglia.aiff</span></span>. If that exists, then we
know this is a resource which the extension provides; but we still give the
project a chance to override that with a file
<span class="extract"><span class="extract-syntax">Project.materials/Sounds/Leipzig Organ Recitals/Passacaglia.aiff</span></span>,
which would be used in preference.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look for an extension resource</span><span class="named-paragraph-number">1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><a href="2-rf.html#SP2" class="function-link"><span class="function-syntax">ResourceFinder::if_present</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">extension_dept</span><span class="plain-syntax">, </span><span class="identifier-syntax">leaf</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pathname</span><span class="plain-syntax"> *</span><span class="identifier-syntax">materials_override</span><span class="plain-syntax"> =</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">Pathnames::down</span><span class="plain-syntax">(</span><span class="identifier-syntax">materials_dept</span><span class="plain-syntax">, </span><span class="identifier-syntax">E</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">as_copy</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">edition</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">work</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">title</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OF</span><span class="plain-syntax"> = </span><a href="2-rf.html#SP2" class="function-link"><span class="function-syntax">ResourceFinder::if_present</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">materials_override</span><span class="plain-syntax">, </span><span class="identifier-syntax">leaf</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">OF</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">OF</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-rf.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_2" class="paragraph-anchor"></a><b>&#167;1.2. </b>Otherwise the resource is not provided by the extension in which the sentence
occurs, or else, the sentence does not occur in an extension. (Of course, this is
by far the most likely thing.) Here we just look in the project's materials folder,
so for example <span class="extract"><span class="extract-syntax">Project.materials/Sounds/Passacaglia.aiff</span></span>.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Look for a regular materials resource</span><span class="named-paragraph-number">1.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::in</span><span class="plain-syntax">(</span><span class="identifier-syntax">materials_dept</span><span class="plain-syntax">, </span><span class="identifier-syntax">leaf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">check_resources_are_present</span><span class="plain-syntax"> == </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">F</span><span class="plain-syntax"> = </span><a href="2-rf.html#SP2" class="function-link"><span class="function-syntax">ResourceFinder::if_present</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">F</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-rf.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>This checks the existence of such a file on disc. We're not going to fret
over the possibility of accidentally opening a directory here.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="function-syntax">ResourceFinder::if_present</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">ResourceFinder::if_present</span></span>:<br/><a href="2-rf.html#SP1_1">&#167;1.1</a>, <a href="2-rf.html#SP1_2">&#167;1.2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">handle</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Filenames::fopen</span><span class="plain-syntax">(</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="string-syntax">"rb"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">handle</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">fclose</span><span class="plain-syntax">(</span><span class="identifier-syntax">handle</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">F</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="1-mm.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-mm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresscurrent">rf</li><li class="progresssection"><a href="2-fgr.html">fgr</a></li><li class="progresssection"><a href="2-se.html">se</a></li><li class="progresssection"><a href="2-ef.html">ef</a></li><li class="progresssection"><a href="2-if.html">if</a></li><li class="progressnext"><a href="2-fgr.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

